package org.ihelpuoo.weboo.tag.ajax;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;

import org.ihelpuoo.I;
import org.ihelpuoo.lang.StringUtils;
import org.ihelpuoo.parser.segment.CharSegment;
import org.ihelpuoo.parser.segment.Segment;
import org.ihelpuoo.parser.segment.SegmentUtils;

public class ViewTag extends AjaxTag
{
	private static final long	serialVersionUID	= 8816859903686194515L;

	protected String			_segmentName;
	protected String			_confSegmentName;
	private String				name;
	private String				type;

	private Segment				_view;
	private Segment				_conf;
	private String				_prefix;

	private List<Segment>		overrides;
	private List<Segment>		children;
	private List<Segment>		getters;
	private List<Segment>		properties;
	private List<Segment>		events;

	public ViewTag()
	{
		_segmentName = "ajax.view";
		_confSegmentName = "ajax.conf";
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getType()
	{
		return type;
	}

	public void setType(String type)
	{
		this.type = type;
	}

	@Override
	protected void start() throws JspException
	{
		reset();
		_view.set("name",name);
		_view.set("type",type);

		overrides = new LinkedList<Segment>();
		children = new LinkedList<Segment>();
		getters = new LinkedList<Segment>();
		properties = new LinkedList<Segment>();
		events = new LinkedList<Segment>();
	}

	private void reset()
	{
		_view = createSegment(_segmentName);
		_conf = null;
		int deep = 1;
		Tag p = this.getParent();
		while (p != null)
		{
			if (p instanceof ViewTag)
				deep++;
			p = p.getParent();
		}
		_prefix = I.NEW_LINE
				+ StringUtils.dup(createSegment("ajax.prefix").toString(),deep).toString();
		/*
		if (null == _view)
			_view = createSegment(segmentName);
		else
			_view.clearAll();
		if (null == _conf)
			_conf = createSegment(confSegmentName);
		else
			_conf.clearAll();
		if (deep < 0)
		{
			deep = 0;
			Tag p = this.getParent();
			while (p != null)
			{
				if (p instanceof ViewTag)
					deep++;
				p = p.getParent();
			}
			_prefix = I.NEW_LINE
				+StringUtils.dup(createSegment("ajax.prefix").toString(),deep).toString();
		}
		*/
	}

	protected void addOverride(OverrideTag tag)
	{
		if (!tag.isAvailable())
			return;
		overrides.add(SegmentUtils.fillBySegment(createSegment("ajax.override"),tag));
	}

	protected void addChild(ChildTag tag)
	{
		children.add(tag.render());
	}

	protected void addEvent(EventTag tag)
	{
		if (!tag.isAvailable())
			return;
		events.add(SegmentUtils.fillBySegment(createSegment("ajax.event"),tag));
	}

	protected void addGetter(GetterTag tag)
	{
		if (!tag.isAvailable())
			return;
		getters.add(SegmentUtils.fillBySegment(createSegment("ajax.get"),tag));
	}

	protected void addProperty(PropertyTag tag)
	{
		if (!tag.isAvailable())
			return;
		properties.add(SegmentUtils.fillBySegment(createSegment("ajax.property"),tag));
	}

	protected void setPattern(PatternTag pattern)
	{
		insert("pattern",pattern);
	}

	protected void setSeed(SpeedTag speed)
	{
		insert("speed",speed);
	}

	protected void setGasket(GasketTag gasket)
	{
		insert("gasket",gasket);
	}

	protected void setPost(PostTag post)
	{
		insert("post",post);
	}

	protected void setToTag(ToTag to)
	{
		insert("to",to);
	}

	@Override
	protected void end() throws JspException
	{
		((RootTag)getParent()).add(this);
	}

	public Segment render()
	{
		compose(children,"children","ajax.children");
		compose(getters,"getters","ajax.getters");
		compose(overrides,"overrides",null);
		compose(events,"events","ajax.events");
		compose(properties,"properties",null);

		return _view.set("conf",_conf);
	}

	private Segment conf()
	{
		if (null == _conf)
			_conf = createSegment(_confSegmentName);
		return _conf;
	}

	private void insert(String key, SettingTag tag)
	{
		if (null != tag && tag.isAvailable())
			conf().set(key,_prefix + tag.toString());
	}

	private void compose(List<Segment> list, String to, String mainName)
	{
		if (list.size() == 0)
			return;
		Segment seg;
		seg = null != mainName ? createSegment(mainName) : new CharSegment("${atts}");
		Iterator<Segment> it = list.iterator();
		int i = 0;
		while (it.hasNext())
		{
			seg.add("atts",_prefix + "\t");
			if (null != mainName && i++ > 0)
				seg.add("atts",",");
			seg.add("atts",it.next());
		}
		conf().add(to,_prefix);
		conf().add(to,seg);
	}
}
